"""
TypeDefinitions.py -- some definitions to handle C++ class informations.

This module contains implementations for an object describing a C++
class, with its members, methods, constructors, ... The idea is to use
the ClassRepresentation to hold the information needed to write actual
header and part of the implementation file, reading the information
from XML file.

Todo :
=====
 * add template classes and methods.
"""

##@package TypeDefinitions
# This module contains implementations for an object describing a C++
# class, with its members, methods, constructors, ... The idea is to
# use the ClassRepresentation to hold the information needed to write
# actual header and part of the implementation file, reading the
# information from XML file.
#
# Contains the classes TypeRepresentation, ArgumentRepresentation,
# MemberRepresentation, ConstructorRepresentation,
# MethodRepresentation and ClassRepresentation.
#
# @author Johan "Solo" Luisier
# @date October 2011

## This class represents what is a C++ "type": the type has a name, like
# unsigned int, string, ... The type is completed by "modifiers" : the
# object can be a reference, a pointer, can be const or not.
#
# @author Johan "Solo" Luisier
# @date October 2011
class TypeRepresentation :
    ## Constructor
    #
    # Initialises the variables, the type name is set to '' and
    # all switches are set to False. 
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        ## Name of the type, i.e. 'unsigned int', 'std::deque< double
        # >', ...
        self.__TypeName = ''
        ## Is \e True if the type is a reference.
        self.__Reference = False
        ## Is \e True if the type is constant.
        self.__Constness = False
        ## Is \e True if the type is a pointer to something.
        self.__Pointer   = False
    ## Allows to change the value of TypeName
    #
    # @param[in] self reference on the calling instance.
    # @param[in] name new value of TypeName
    #
    # @return value of TypeName
    def setTypeName( self, name ) :
        self.__TypeName = name
        return self.__TypeName
    ## Allows to access TypeName
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of TypeName
    def getTypeName( self ) :
        return self.__TypeName
    ## Allows to change the Reference switch
    #
    # @param[in] self reference of the calling instance
    # @param[in] boolean new value of Reference
    #
    # @return value of Reference
    def setReference( self, boolean ) :
        self.__Reference = boolean
        return self.__Reference
    ## Allows to access Reference switch value.
    #
    # @return value of Reference.
    def getReference( self ) :
        return self.__Reference
    ## Allows to change the value of Constness switch.
    #
    # @param[in] self reference of the calling instance.
    # @param[in] boolean new value of Constness.
    #
    # @return value of Constness.
    def setConstness( self, boolean ) :
        self.__Constness = boolean
        return self.__Constness
    ## Allows to access Constness switch value.
    #
    # @return value of Constness.
    def getConstness( self ) :
        return self.__Constness
    ## Allows to change the value of Pointer switch.
    #
    # @param[in] self reference of the calling instance.
    # @param[in] boolean new value of Pointer.
    #
    # @return value of Pointer.
    def setPointer( self, boolean ) :
        self.__Pointer = boolean;
        return self.__Pointer
    ## Allows to access Pointer switch value.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of Pointer.
    def getPointer( self ) :
        return self.__Pointer
    ## Allows to print the type.
    # If the variable / function / argument is a reference \e and a
    # pointer, this will be written as type*& (i.e. a reference on a
    # pointer).
    #
    # @param[in] self reference of the calling instance.
    # @param[in] header switches between header and implementation
    # line production (does not change anything in this particular
    # case).
    def produceLine( self, header=False ) :
        string = str()
        if ( self.getConstness() == True ) :
            string += "const "
        string += self.getTypeName()
        if ( self.getPointer() == True ) :
            string += "*"
        if ( self.getReference() == True ) :
            string += "&"
        return string

## Class implementing an argument (of a function, method, ...). An
# argument has a name, and is a variable, therefore the
# ArgumentRepresentation class inherits from TypeRepresentation.
#
# @author Johan "Solo" Luisier
# @date October 2011
class ArgumentRepresentation( TypeRepresentation ) :
    ## Constructor
    # The constructor relies on TypeRepresentation.__init__
    # constructor, and initialises the Name member.
    #
    # @param[in] self reference on calling instance.
    def __init__( self ) :
        TypeRepresentation.__init__( self )
        self.__Name    = ''
        self.__Default = ''
    ## Allows to change the name of the argument.
    #
    # @param[in] self reference on calling instance.
    # @param[in] argName new value of Name.
    #
    # @return value of Name.
    def setName( self, argName ) :
        self.__Name = argName
        return self.__Name
    ## Allows to access the Name member.
    #
    # @return value of Name.
    def getName( self ) :
        return self.__Name
    ## Allows to change the default value of the argument.
    #
    # @param[in] self reference on calling instance.
    # @param[in] argDefault new value of Default.
    #
    # @return the value of __Default.
    def setDefault( self, argDefault ) :
        self.__Default = argDefault
        return self.__Default
    ## Allows to access the default value of the argument.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of __Default.
    def getDefault( self ) :
        return self.__Default
    ## Produces the usual output.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the '[const] type[*][&] varname' line.
    # @param[in] header switches between header and implementation
    # line production.
    #
    # @return the [const] type[*][&] name [= default]' string.
    def produceLine( self, header=False ) :
        string = TypeRepresentation.produceLine( self )
        string += " " + self.getName()
        if ( header and self.getDefault() != '' ) :
            string += " = " + self.getDefault()
        return string
    ## Produces the comment output.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the line '* \@param[] name' corresponding to the
    # argument.
    def produceComment( self ) :
        string = '  * @param'
        if ( self.getReference() and self.getConstness() ) :
            string +=  '[in] '
        elif ( self.getReference() ) :
            string +=  '[out] '
        else :
            string += ' '
        string += self.getName() + ' \n'
        return string

## Class representing a C++ class member.
# A C++ class member has a type (thus MemberRepresentation inherits
# from TypeRepresentation) and a name. A class member is usually not
# public, therefore get/set methods are needed to access and change
# its value. A member can also be static.
#
# @author Johan "Solo" Luisier
# @date October 2011
class MemberRepresentation( TypeRepresentation ) :
    ## Constructor
    # It relies on the contructor of TypeRepresentation, and
    # initialises specific members. The name is '' and all switches
    # are set to \e False.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        TypeRepresentation.__init__( self )
        self.__Name    = ''
        self.__StdGet  = True
        self.__StdSet  = True
        self.__PtrGet  = False
        self.__PtrSet  = False
        self.__Mutable = False
        self.__Static  = False
        self.__Value   = ''
    ## Allows to change the value of Name.
    #
    # @param[in] argName new value of Name.
    #
    # @return value of Name.
    def setName( self, argName ) :
        self.__Name = argName
        return self.__Name
    ## Allows to access the value of Name.
    #
    # @return value of Name.
    def getName( self ) :
        return self.__Name
    ## Allows to change the value of the StdGet switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of StdGet.
    #
    # @return value of StdGet.
    def setStdGet( self, boolean ) :
        self.__StdGet = boolean
        if ( not self.__StdGet ) :
            self.__Value = ''
        return self.__StdGet
    ## Allows to access the value of the StdGet switch
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of StdGet.
    def getStdGet( self ) :
        return self.__StdGet
    ## Allows to change the value of the StdSet switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of StdSet.
    #
    # @return value of StdSet.
    def setStdSet( self, boolean ) :
        self.__StdSet = boolean
        if ( not self.__StdSet ) :
            self.__Value = ''
        return self.__StdSet
    ## Allows to access the value of the StdSet switch
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of StdSet.
    def getStdSet( self ) :
        return self.__StdSet
    ## Allows to change the value of the PtrGet switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of PtrGet.
    #
    # @return value of PtrGet.
    def setPtrGet( self, boolean ) :
        self.__PtrGet = boolean
        if ( not self.__PtrGet ) :
            self.__Value = ''
        return self.__PtrGet
    ## Allows to access the value of the PtrGet switch.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of PtrGet.
    def getPtrGet( self ) :
        return self.__PtrGet
    ## Allows to change the value of the PtrSet switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of PtrSet.
    #
    # @return value of PtrSet.
    def setPtrSet( self, boolean ) :
        self.__PtrSet = boolean
        if ( not self.__PtrSet ) :
            self.Value = ''
        return self.__PtrSet
    ## Allows to access the value of the PtrSet switch.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of PtrSet.
    def getPtrSet( self ) :
        return self.__PtrSet
    ## Allows to change the value of the Mutable switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of Mutable.
    #
    # @return value of Mutable.
    def setMutable( self, boolean ) :
        self.__Mutable = boolean
        return self.__Mutable
    ## Allows to access the value of the Mutable switch
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of Mutable.
    def getMutable( self ) :
        return self.__Mutable
    ## Allows to change the value of the Static switch.
    #
    # If the switch is set to \e False, the default value is reset to
    # ''.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of Static.
    #
    # @return value of Static.
    def setStatic( self, boolean ) :
        self.__Static = boolean
        if ( not self.__Static ) :
            self.Value = ''
        return self.__Static
    ## Allows to access the value of the Static switch
    #
    # @return value of Static.
    def getStatic( self ) :
        return self.__Static
    ## Allows to change the default value of the member (if static).
    #
    # If the method is called, the Static switch is automatically set
    # to \e True.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] defValue new value of Value.
    #
    # @return value of Value.
    def setValue( self, defValue ) :
        self.__Static = True
        self.__Value = defValue
        return self.__Value
    ## Allows to access the value of Value.
    #
    # @return value of Value.
    def getValue( self ) :
        return self.__Value
    ## Produces the usual output.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] header switches between header and implementation
    # line production.
    #
    # @return the line '[const] type[*][&] name;' in the header case,
    # and adds a '{0}::' before the name and the '( value )' in the
    # implementation case.
    def produceLine( self, header ) :
        string = str()
        if ( self.getStatic() and header ) :
            string += 'static '
        if ( self.getMutable() and header ) :
            string += 'mutable '
        string += TypeRepresentation.produceLine( self, False )
        if ( header ) :
            string += ' ' + self.getName() + ';'
        elif ( not header and self.getStatic() ) :
            string += ' {0}::' + self.getName() + '( ' + self.getValue() + ' );'
        else :
            string = ''
        return string
    ## Produces the comment lines.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return an empty comment.
    def produceComment( self ) :
        return '/**\n  *\n  */'

## Class representing a very basic "function", it is not meant to be
# used directly, but is the mother of the Constructor and Method
# classes. The common part between these two categories are the name
# and a list of arguments.
#
# @author Johan "Solo" Luisier
# @date October 2011
class _FBaseRepresentation :
    ## Constructor
    # Initialises the name (to an empty string) and the argument list
    # (to an empty array).
    #
    # @param[in] self reference on the calling instance
    def __init__( self ) :
        self.__Name = ''
        self.__ArgList = []
        self.__FunctionConstness = False
        self.__Body = ''
        self.__Comments = ''
        self.__Static      = False
        self.__Virtual     = False
        self.__PureVirtual = False
    ## Allows to change the name of the function.
    #
    # @param[in] self reference on calling instance.
    # @param[in] fName new value of Name.
    #
    # @return value of Name.
    def setName( self, fName ) :
        self.__Name = fName
        return self.__Name
    ## Allows to access the name of the function.
    #
    # @return value of Name.
    def getName( self ) :
        return self.__Name
    ## Allows to add an argument to the argument list.
    #
    # @param[in] self reference on calling instance.
    # @param[in] arg instance of argument to be added.
    #
    # @return nbr of arguments.
    def addArgument( self, arg ) :
        self.__ArgList.append( arg )
        return len( self.__ArgList )
    ## Allows to access the list of arguments.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the list of arguments.
    def getArguments( self ) :
        return self.__ArgList
    ## Allows to change the "function constness", i.e. the fact that
    # the given method does not change the class members.
    #
    # @param[in] self reference on calling instance.
    # @param[in] functionConstness new value of __FunctionConstness.
    #
    # @return the value of __FunctionConstness.
    def setFunctionConstness( self, functionConstness ) :
        self.__FunctionConstness = functionConstness
        return self.__FunctionConstness
    ## Allows to access the "function constness"
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of __FunctionConstness.
    def getFunctionConstness( self ) :
        return self.__FunctionConstness
    ## Allows to change the function body.
    #
    # @param[in] self reference on calling instance.
    # @param[in] body new value of __Body.
    #
    # @return the value of __Body.
    def setBody( self, body ) :
        self.__Body = body
        return self.__Body
    ## Allows to access the body of the function.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of __Body.
    def getBody( self ) :
        return self.__Body
    ## Allows to change the function comments.
    #
    # @param[in] self reference on calling instance.
    # @param[in] comments new value of __Comments.
    #
    # @return the value of __Comments.
    def setComments( self, comments ) :
        self.__Comments = comments
        return self.__Comments
    ## Allows to access the comments of the function.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of __Comments.
    def getComments( self ) :
        return self.__Comments
    ## Allows to change the value of the Static switch.
    #
    # @param[in] boolean new value of Static.
    #
    # @return value of Static.
    def setStatic( self, boolean ) :
        self.__Static = boolean
        return self.__Static
    ## Allows to access the value of the Static switch
    #
    # @return value of Static.
    def getStatic( self ) :
        return self.__Static
    ## Allows to change the value of the Virtual switch.
    #
    # @param[in] boolean new value of Virtual.
    #
    # @return value of Virtual.
    def setVirtual( self, boolean ) :
        self.__Virtual = boolean
        return self.__Virtual
    ## Allows to access the value of the Virtual switch
    #
    # @return value of Virtual.
    def getVirtual( self ) :
        return self.__Virtual
    ## Allows to change the value of the PureVirtual switch.
    #
    # @param[in] boolean new value of PureVirtual.
    #
    # @return value of PureVirtual.
    def setPureVirtual( self, boolean ) :
        self.__PureVirtual = boolean
        if ( self.__PureVirtual ) :
            self.__Virtual = ''
        return self.__PureVirtual
    ## Allows to access the value of the PureVirtual switch
    #
    # @return value of PureVirtual.
    def getPureVirtual( self ) :
        return self.__PureVirtual
    ## Produces the usual output.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] header switches between header and implementation
    # line production.
    #
    # @return the line 'name( args );' if the header case, for the
    # implementation, a '{0}::' is prepended to the function name.
    def produceLine( self, header ) :
        string = str()
        if ( not header ) :
            string += '{0}::'
        string += self.getName()
        if ( len( self.getArguments() ) > 0 ) :
            string += '( '
            for arg in self.getArguments() :
                string += arg.produceLine( header )
                if ( self.getArguments().index( arg ) != len( self.getArguments() ) - 1 ) :
                    string += ", "
            string += " )"
        else :
            string += "()"
        if ( self.getFunctionConstness() ) :
            string += ' const'
        return string

## Class representing a constructor, a constructor is a function which
# has no return type. It is actually just an alias for the
# _FBaseRepresentation class.
#
# This type is also used to represent the destructor, since a
# destructor is a method without any return type.
#
# @author Johan "Solo" Luisier
# @date October 2011
class ConstructorRepresentation( _FBaseRepresentation ) :
    ## Constructor
    # Initialises the base class.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        _FBaseRepresentation.__init__( self )
    ## Produces the usual print out.
    #
    # @param[in] self reference on calling instance.
    # @param[in] header switch between header (\e True) or
    # implementation file (\e False) production.
    #
    # @return the name of the constructor, followed by its aguments.
    def produceLine( self, header ) :
        string = str()
        if ( self.getVirtual() and header ) :
            string += 'virtual '
        string += _FBaseRepresentation.produceLine( self, header )
        if ( not header ) :
            pass
        else :
            string += ';'
        return string
    ## Produces the comments.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the comments.
    def produceComment( self ) :
        if ( self.getComments() != '' ) : return self.getComments()
        string = "/** {0}\n  *\n  *\n"
        if ( len( self.getArguments() ) > 0 ) :
            for arg in self.getArguments() :
                string += arg.produceComment()
        string += "  */"
        return string;

## Class representing a method : a method is a function with a type (its
# return type). This is why it inherits from both
# _FBaseRepresentation and TypeRepresentation.
#
# @author Johan "Solo" Luisier
# @date October 2011
class MethodRepresentation( _FBaseRepresentation, TypeRepresentation ) :
    ## Constructor
    # Initialises the two mother classes.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        _FBaseRepresentation.__init__( self )
        TypeRepresentation.__init__( self )
    ## Produces the usual print out.
    #
    # @param[in] self reference on calling instance.
    # @param[in] header switch between header (\e True) or
    # implementation file (\e False) production.
    #
    # @return a string containing the return type, the method name and
    # arguments.
    def produceLine( self, header ) :
        string = str()
        if ( self.getPureVirtual() and not header ) :
            return string
        if ( self.getStatic() and header ) :
            string += 'static '
        if ( self.getVirtual() and header ) :
            string += 'virtual '
        string = TypeRepresentation.produceLine( self ) + ' '
        string += _FBaseRepresentation.produceLine( self, header )
        if ( self.getPureVirtual() and header ) :
            string += ' = 0'
        if ( not header ) :
            pass
        else :
            string += ';'
        return string
    ## Produces the comments.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the comments.
    def produceComment( self ) :
        if ( self.getComments() != '' ) : return self.getComments()
        string = "/**\n  *\n  *\n"
        if ( len( self.getArguments() ) > 0 ) :
            for arg in self.getArguments() :
                string += arg.produceComment()
        string += "  */"
        return string

## Class representing a C++ class. A C++ class is defined by its name,
# the namespace it belongs to, a list of constructors, methods and
# members. Additional information are also provided, like the name of
# the author and the date of creation.
#
# @author Johan "Solo" Luisier
# @date October 2011
class ClassRepresentation :
    ## Constructor
    # Initialises the members. All names are set to an empty string
    # and the lists are set to empty arrays.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        self.__ClassName = ''
        self.__Namespace = ''
        self.__Author    = ''
        self.__Date      = ''
        self.__Inherits  = []
        self.__PublicConstr = []
        self.__PublicMethod = []
        self.__PublicMember = []
        self.__ProtectedConstr = []
        self.__ProtectedMethod = []
        self.__ProtectedMember = []
        self.__PrivateConstr = []
        self.__PrivateMethod = []
        self.__PrivateMember = []
        self.__ForwardDeclaration = []
        self.__LocalHeaderIncludes = []
        self.__DistantHeaderIncludes = []
        self.__LocalImplementationIncludes = []
        self.__DistantImplementationIncludes = []
        self.__HeaderUsingNamespace = []
        self.__ImplementationUsingNamespace = []
        self.__AutomaticMethods = {}
    ## Allows to change the name of the class.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] className new value of ClassName.
    #
    # @return value of ClassName.
    def setClassName( self, className ) :
        self.__ClassName = className;
        return self.__ClassName
    ## Allows to get the value of the class name.
    #
    # @return value of ClassName
    def getClassName( self ) :
        return self.__ClassName
    ## Allows to change the namespace of the class.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] namespace new value of Namespace.
    #
    # @return value of Namespace.
    def setNamespace( self, namespace ) :
        self.__Namespace = namespace;
        return self.__Namespace
    ## Allows to get the value of the class namespace.
    #
    # @return value of Namespace.
    def getNamespace( self ) :
        return self.__Namespace
    ## Allows to change the author name
    #
    # @param[in] self reference on the calling instance.
    # @param[in] author new value of Author.
    #
    # @return value of Author.
    def setAuthor( self, author ) :
        self.__Author = author
        return self.__Author
    ## Allows to access the name of the author.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of Author.
    def getAuthor( self ) :
        return self.__Author
    ## Allows to change the creation date.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] date new value of Date.
    #
    # @return value of Date.
    def setDate( self, date ) :
        self.__Date = date
        return self.__Date
    ## Allows to access the creation date.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of Date
    def getDate( self ) :
        return self.__Date
    ## Allows to add an inheritance relation.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] name name of the mother class.
    # @param[in] access access type.
    # @param[in] virtual virtual inheritance switch, is '' if the
    # inheritance is standard, or 'virtual' if the inheritance is
    # virtual.
    #
    # @return number of inheritance relations.
    def addInherits( self, name, access, virtual='' ) :
        self.__Inherits.append( [ name, access, virtual ] )
        if ( self.__Inherits[ -1 ][ 2 ] != '' ) :
            self.__Inherits[ -1 ][ 2 ] += ' '
        return len( self.__Inherits )
    ## Allows to access the list of inheritance relations
    #
    # @param[in] self reference on the calling instance.
    #
    # @return an array containing the inheritance relations.
    def getInherits( self ) :
        return self.__Inherits
    ## Allows to add a \e public constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] constructor instance of constructor to be added.
    #
    # @return number of \e public constructors.
    def addPublicConstructor( self, constructor ) :
        self.__PublicConstr.append( constructor )
        return len( self.__PublicConstr )
    ## Allows to access the list of \e public constructors.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e public constructors.
    def getPublicConstructors( self ) :
        return self.__PublicConstr
    ## Allows to add a \e public method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] method instance of method to be added.
    #
    # @return the number of \e public methods.
    def addPublicMethod( self, method ) :
        self.__PublicMethod.append( method )
        return len( self.__PublicMethod )
    ## Allows to access the list of \e public methods.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e public methods.
    def getPublicMethods( self ) :
        return self.__PublicMethod
    ## Allows to add a \e public member.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] member instance of memeber to be added.
    #
    # @return the number of \e public members.
    def addPublicMember( self, member ) :
        self.__PublicMember.append( member )
        return len( self.__PublicMember )
    ## Allows to access the list of \e public members.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of public members.
    def getPublicMembers( self ) :
        return self.__ProtectedMember
    ## Allows to get the total number of \e public objects.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the sum of the lengths of PublicConstrutror,
    # PublicMethod and PublicMember.
    def getNbrPublicItems( self ) :
        result = len( self.__PublicConstr )
        result += len( self.__PublicMethod )
        result += len( self.__PublicMember )
        return result
    ## Allows to add a \e protected constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] constructor instance of constructor to be added.
    #
    # @return number of \e protected constructors.
    def addProtectedConstructor( self, constructor ) :
        self.__ProtectedConstr.append( constructor )
        return len( self.__ProtectedConstr )
    ## Allows to access the list of \e protected constructors.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e protected constructors.
    def getProtectedConstructors( self ) :
        return self.__ProtectedConstr
    ## Allows to add a \e protected method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] method instance of method to be added.
    #
    # @return the number of \e protected methods.
    def addProtectedMethod( self, method ) :
        self.__ProtectedMethod.append( method )
        return len( self.__ProtectedMethod )
    ## Allows to access the list of \e protected methods.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e protected methods.
    def getProtectedMethods( self ) :
        return self.__ProtectedMethod
    ## Allows to add a \e protected member.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] member instance of memeber to be added.
    #
    # @return the number of \e protected members.
    def addProtectedMember( self, member ) :
        self.__ProtectedMember.append( member )
        return len( self.__ProtectedMember )
    ## Allows to access the list of \e protected members.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of protected members.
    def getProtectedMembers( self ) :
        return self.__ProtectedMember
    ## Allows to get the total number of \e protected objects.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the sum of the lengths of ProtectedConstrutror,
    # ProtectedMethod and ProtectedMember.
    def getNbrProtectedItems( self ) :
        result = len( self.__ProtectedConstr )
        result += len( self.__ProtectedMethod )
        result += len( self.__ProtectedMember )
        return result
    ## Allows to add a \e private constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] constructor instance of constructor to be added
    #
    # @return number of \e private constructors.
    def addPrivateConstructor( self, constructor ) :
        self.__PrivateConstr.append( constructor )
        return len( self.__PrivateConstr )
    ## Allows to access the list of \e private constructors.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e private constructors.
    def getPrivateConstructors( self ) :
        return self.__PrivateConstr
    ## Allows to add a \e private method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] method instance of method to be added.
    #
    # @return the number of \e private methods.
    def addPrivateMethod( self, method ) :
        self.__PrivateMethod.append( method )
        return len( self.__PrivateMethod )
    ## Allows to access the list of \e private methods.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e private methods.
    def getPrivateMethods( self ) :
        return self.__PrivateMethod
    ## Allows to add a \e private member.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] member instance of memeber to be added.
    #
    # @return the number of \e private members.
    def addPrivateMember( self, member ) :
        self.__PrivateMember.append( member )
        return len( self.__PrivateMember )
    ## Allows to access the list of \e private members.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of private members.
    def getPrivateMembers( self ) :
        return self.__PrivateMember
    ## Allows to get the total number of \e private objects.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the sum of the lengths of PrivateConstrutror,
    # PrivateMethod and PrivateMember.
    def getNbrPrivateItems( self ) :
        result = len( self.__PrivateConstr )
        result += len( self.__PrivateMethod )
        result += len( self.__PrivateMember )
        return result
    ## Allows to add a forward declaration.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] string forward declaration string.
    #
    # @return the number of existing forward declarations.
    def addForwardDeclaration( self, string ) :
        self.__ForwardDeclaration.append( string )
        return len( self.__ForwardDeclaration )
    ## Allows to access the list of forward declarations.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return an array containing the forward declarations.
    def getForwardDeclaration( self ) :
        return self.__ForwardDeclaration
    ## Allows to add a include in the header file. There are local and
    # distant inclusions, local means that the file is a header
    # written by the user, present somewhere in the compiled
    # code. Distant means that the header in present in /usr/include/
    # or equivalent.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] string forward declaration string.
    # @param[in] local boolean value, \e True if include is local, \e
    # False if distant.
    #
    # @return the number of includes in the header file (for the given
    # local or distant category).
    def addHeaderInclude( self, string, local=False ) :
        if ( local ) :
            self.__LocalHeaderIncludes.append( string )
            return len( self.__LocalHeaderIncludes )
        else :
            self.__DistantHeaderIncludes.append( string )
            return len( self.__DistantHeaderIncludes )
    ## Allows to access the list of includes made in the header file
    # (local or distant).
    #
    # @param[in] self reference on the calling instance.
    # @param[in] local switch between local (\e True) and system
    # header files to be included (\e False).
    #
    # @return an array containing the list of includes.
    def getHeaderInclude( self, local=False ) :
        if ( local ) : return self.__LocalHeaderIncludes
        else : return self.__DistantHeaderIncludes
    ## Allows to add a include in the implementation file. There are
    # local and distant inclusions, local means that the file is a
    # implementation written by the user, present somewhere in the
    # compiled code. Distant means that the implementation in present
    # in /usr/include/ or equivalent.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] string forward declaration string.
    # @param[in] local boolean value, \e True if include is local, \e
    # False if distant.
    #
    # @return the number of includes in the implementation file (for
    # the given local or distant category).
    def addImplementationInclude( self, string, local=False ) :
        if ( local ) :
            self.__LocalImplementationIncludes.append( string )
            return len( self.__LocalImplementationIncludes )
        else :
            self.__DistantImplementationIncludes.append( string )
            return len( self.__DistantImplementationIncludes )
    ## Allows to access the list of includes made in the implementation
    # file (local or distant).
    #
    # @param[in] self reference on the calling instance.
    # @param[in] local switch between local (\e True) and system
    # header files to be included (\e False).
    #
    # @return an array containing the list of includes.
    def getImplementationInclude( self, local=False ) :
        if ( local ) : return self.__LocalImplementationIncludes
        else : return self.__DistantImplementationIncludes
    ## Allows to add a 'using namespace'.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] namespace name of the namespace to be added.
    # @param[in] header switch to add a 'using namespace' in the
    # header file (if \e True) or in the implementation (\e False ).
    #
    # @return number of 'using namespace' statements (either in the
    # header or in the implementation depending on the value of the
    # switch \c header).
    def addUsingNamespace( self, namespace, header ) :
        if ( header ) :
            self.__HeaderUsingNamespace.append( namespace )
            return len( self.__HeaderUsingNamespace )
        else :
            self.__ImplementationUsingNamespace.append( namespace )
            return len( self.__ImplementationUsingNamespace )
    ## Allows to get the 'using namespace'.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] header switch to add a 'using namespace' in the
    # header file (if \e True) or in the implementation (\e False ).
    #
    # @return an array containing the list of 'using namespace'
    # statements (either in the header or in the implementation
    # depending on the value of the switch \c header).
    def getUsingNamespace( self, header ) :
        if ( header ) :
            return self.__HeaderUsingNamespace
        else :
            return self.__ImplementationUsingNamespace
    ## Allows to add an automatic method.
    # Before each insertion, it is checked whether there is already
    # such a method with another access specifier. If such a method is
    # found, nothing is added.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] what name of the item which will be added.
    # @param[in] access access specifier of the item.
    #
    # @return \e True if the addition could be made without problems,
    # \e False if a similar method is already present with another
    # access specifier.
    def addAutomaticMethod( self, what, access ) :
        if ( what in self.__AutomaticMethods.keys() ) :
            return False
        tmpDict = { what : access }
        self.__AutomaticMethods.update( tmpDict )
        return True
    ## Allows to get the dictionnary of automatic methods.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the dictionnary __AutomaticMethods
    def getAutomaticMethods( self ) :
        return self.__AutomaticMethods
    ## Allows to get the total number of members (without the static
    # ones).
    #
    # First gets the list of non-static members from
    # getNonStaticMembers.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the number of non-static members.
    def getNbrNonStaticMembers( self ) :
        return len( self.getNonStaticMembers() )
    ## Allows to get the list of \e all non-static members.
    # ones).
    #
    # @param[in] self reference on the calling instance.
    #
    # @return an array containing the non-static members.
    def getNonStaticMembers( self ) :
        results = []
        for member in self.__PublicMember :
            if ( not member.getStatic() ) :
                results.append( member.getName() )
        for member in self.__ProtectedMember :
            if ( not member.getStatic() ) :
                results.append( member.getName() )
        for member in self.__PrivateMember :
            if ( not member.getStatic() ) :
                results.append( member.getName() )
        return results
    ## Allows to print the instance in its header file.
    #
    # @param[in] self reference on the calling instance. 
    # @param[in] stream output stream used to print the data.
    # @param[in] comments toggles on/off comments printing
    def writeHeader( self, stream, comments ) :
        stream.write( "/**\n * @author "+ self.getAuthor() + "\n" )
        stream.write( " * @date " + self.getDate()  + "\n" )
        stream.write( " */"  + "\n" )
        prefix = ''
        if ( self.getNamespace() != '' ) :
            stream.write( "namespace " + self.getNamespace() + "\n{\n" )
            prefix = ' '
        line = str( '' )
        line = "class " + self.getClassName()
        for iMother in range( len( self.__Inherits ) ) :
            mother = self.__Inherits[ iMother ]
            if ( iMother == 0 ) :
                line += " : "
            else :
                line += ", "
            line += mother[ 1 ] + " " + mother[ 2 ] + mother[ 0 ]
        stream.write( prefix + line  + "\n" )
        stream.write( prefix + "{\n" + prefix + "public:\n" )
        for displayItem in self.__PublicConstr :
            self._writeItemHeader( stream, displayItem, comments, prefix)
        for displayItem in self.__PublicMethod :
            self._writeItemHeader( stream, displayItem, comments, prefix )
        for displayItem in self.__PublicMember :
            self._writeItemHeader( stream, displayItem, comments, prefix )
        if ( self.getNbrProtectedItems() > 0 ) :
            stream.write( prefix + "protected:\n" )
            for displayItem in self.__ProtectedConstr :
                self._writeItemHeader( stream, displayItem, comments, prefix )
            for displayItem in self.__ProtectedMethod :
                self._writeItemHeader( stream, displayItem, comments, prefix )
            for displayItem in self.__ProtectedMember :
                self._writeItemHeader( stream, displayItem, comments, prefix )
        if ( self.getNbrPrivateItems() > 0 ) :
            stream.write( prefix + "private:\n" )
            for displayItem in self.__PrivateConstr :
                self._writeItemHeader( stream, displayItem, comments, prefix )
            for displayItem in self.__PrivateMethod :
                self._writeItemHeader( stream, displayItem, comments, prefix )
            for displayItem in self.__PrivateMember :
                self._writeItemHeader( stream, displayItem, comments, prefix )
        stream.write( prefix + "};\n" )
        if ( self.getNamespace() != '' ) :
            stream.write( "}" )
    ## Helper function to avoid code duplication in the writeHeader
    ## method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] item item for which the print out has to be done.
    def _writeItemHeader( self, stream, item, comments, prefix ) :
        strLine, strComment = ( item.produceLine( True ), item.produceComment() )
        if ( comments and prefix != '' ) :
            stream.write( prefix + strComment.replace( '\n', '\n' + prefix ) + '\n' )
        elif ( comments ) :
            stream.write( ' ' + strComment + '\n' )
        stream.write( prefix + " " + self._removeNamespace( strLine, True ) + '\n' )
    ## Allows to print the instance in its implementation file.
    #
    # @param[in] self reference on the calling instance. 
    # @param[in] stream output stream used to print the data.
    def writeImplementation( self, stream ) :
        if ( self.getNamespace() != '' ) :
            stream.write( 'using namespace ' + self.getNamespace() + ';\n\n' )

        prefix = ''
        
        for displayItem in self.__PublicConstr :
            self._writeItemImplementation( stream, displayItem, prefix )
            stream.write( displayItem.getBody() + '\n\n' )
        for displayItem in self.__PublicMethod :
            self._writeItemImplementation( stream, displayItem, prefix )
            stream.write( displayItem.getBody() + '\n\n' )
        for displayItem in self.__PublicMember :
            self._writeItemImplementation( stream, displayItem, prefix )
        if ( self.getNbrProtectedItems() > 0 ) :
            for displayItem in self.__ProtectedConstr :
                self._writeItemImplementation( stream, displayItem, prefix )
                stream.write( displayItem.getBody() + '\n\n' )
            for displayItem in self.__ProtectedMethod :
                self._writeItemImplementation( stream, displayItem, prefix )
                stream.write( displayItem.getBody() + '\n\n' )
            for displayItem in self.__ProtectedMember :
                self._writeItemImplementation( stream, displayItem, prefix )
        if ( self.getNbrPrivateItems() > 0 ) :
            for displayItem in self.__PrivateConstr :
                self._writeItemImplementation( stream, displayItem, prefix )
                stream.write( displayItem.getBody() + '\n\n' )
            for displayItem in self.__PrivateMethod :
                self._writeItemImplementation( stream, displayItem, prefix )
                stream.write( displayItem.getBody() + '\n\n' )
            for displayItem in self.__PrivateMember :
                self._writeItemImplementation( stream, displayItem, prefix )
    ## Helper function to avoid code duplication in the
    # writeImplementation method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] item item for which the print out has to be done.
    def _writeItemImplementation( self, stream, item, prefix ) :
        strLine = item.produceLine( False )
        strLine = strLine.format( self.getClassName() )
        stream.write( prefix + self._removeNamespace( strLine, False ) + '\n' )
    ## Function which removes any mention of 'namespace::' for each
    # namespace used.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] string character string to be processed.
    # @param[in] header switch to add a 'using namespace' in the
    # header file (if \e True) or in the implementation (\e False ).
    #
    # @return the character string \c string with the 'namespace::'
    # removed.
    def _removeNamespace( self, string, header ):
        listOfNamespaces = self.getUsingNamespace( header )

        for namespace in listOfNamespaces :
            toDelete = namespace + '::'
            string = string.replace( toDelete, '' )
        
        return string
        
        
